<?php

namespace app\admin\service;

use app\admin\common\ServiceResponse;
use app\admin\model\Operator;
use app\admin\model\OrderPartDeliveryApply as OrderPartDeliveryApplyModel;
use app\admin\model\OrderPartDeliveryApplyItem as OrderPartDeliveryApplyItemModel;
use app\admin\model\Order as OrderModel;
use app\admin\model\OrderItem as OrderItemModel;
use app\admin\model\SystemConfig as SystemConfigModel;
use think\facade\Db;
use think\exception\ValidateException;
use app\common\service\CompleteNotificationService;

class OrderPartDeliveryApply extends BaseService
{
    use ServiceResponse;

    protected $model;
    protected $itemModel;
    protected $orderModel;
    protected $orderItemModel;

    public function __construct()
    {
        $this->model = new OrderPartDeliveryApplyModel();
        $this->itemModel = new OrderPartDeliveryApplyItemModel();
        $this->orderModel = new OrderModel();
        $this->orderItemModel = new OrderItemModel();
        parent::__construct();
    }

    /**
     * @describe 获取部分发货申请列表
     * @param array $where 查询条件
     * @return array
     *
     * @return array 返回数据结构：
     * [
     *     {
     *         "id": "申请ID",
     *         "order_id": "订单ID",
     *         "remark": "备注",
     *         "status": "状态 1待审核 2已审核",
     *         "status_text": "状态文本",
     *         "create_time": "创建时间",
     *         "creator": "创建人",
     *         "items": {
     *             "order_item_id": "订单项ID",
     *             "warehouse_id": "仓库ID",
     *             "fl_warehouse_id": "头程仓库ID",
     *             "product_id": "商品ID",
     *             "is_futures": "是否期货",
     *             "arrival_date": "到货日期",
     *             "real_arrival_date": "实际到货日期",
     *             "apply_quantity": "申请数量",
     *             "pending_quantity": "待发数量",
     *             "code": "商品编码",
     *             "name": "商品名称",
     *             "hashrate": "算力",
     *             "expiration_date": "过期日期",
     *             "original_price": "原价",
     *             "actual_price": "实际价格",
     *             "free_shipping": "是否包邮",
     *             "apply_rules": "是否应用规则",
     *             "brand": "品牌",
     *             "actual_quoted_currency": "实际报价币种",
     *             "actual_quoted_currency_name": "实际报价币种名称",
     *             "billing_weight": "计费重量",
     *             "pay_quantity": "支付数量",
     *             "unique": "唯一标识"
     *         }
     *     }
     * ]
     */
    public function getList($where): array
    {
        $list = $this->model->where($where)
            ->order('create_time desc')
            ->select()
            ->toArray();

        if (empty($list)) {
            return $this->success([]);
        }

        // 获取所有申请项
        $applyIds = array_column($list, 'id');
        $items = $this->itemModel->where('order_part_delivery_apply_id', 'in', $applyIds)
            ->where('is_del', 0)
            ->select()
            ->toArray();

        // 获取所有订单项信息（带关联）
        $orderItemIds = array_column($items, 'order_item_id');
        $orderItems = $this->orderItemModel->with(['productForOrder', 'warehouses'])
            ->where('id', 'in', $orderItemIds)
            ->select()
            ->toArray();

        // 获取币种信息
        $transactionCurrencyIds = array_unique(array_column($orderItems, 'transaction_currency_id'));
        $currencyNames = Db::table('db_transaction_currency')
            ->whereIn('id', $transactionCurrencyIds)
            ->column('name', 'id');

        // 获取创建者信息
        $creatorIds = array_unique(array_column($items, 'creator'));
        $creatorNames = Operator::whereIn('id', $creatorIds)
            ->column('cname', 'id');

        // 组装数据
        $result = [];
        foreach ($list as $apply) {
            $applyData = [
                'id' => $apply['id'],
                'order_id' => $apply['order_id'],
                'remark' => $apply['remark'],
                'status' => $apply['status'],
                'status_text' => $apply['status'] == 1 ? '待审核' : '已审核',
                'create_time' => $apply['create_time'],
                'creator' => $apply['creator'],
                'items' => []
            ];

            foreach ($items as $item) {
                if ($item['order_part_delivery_apply_id'] == $apply['id']) {
                    // 找到对应的订单项
                    $orderItem = null;
                    foreach ($orderItems as $oi) {
                        if ($oi['id'] == $item['order_item_id']) {
                            $orderItem = $oi;
                            break;
                        }
                    }

                    if ($orderItem) {
                        $fl_warehouse_id = isset($orderItem['warehouses']) ? $orderItem['warehouses']['fl_warehouse_id'] : null;
                        $currencyName = isset($orderItem['transaction_currency_id']) ? ($currencyNames[$orderItem['transaction_currency_id']] ?? '') : '';

                        $applyData['items'][] = [
                            'order_item_id' => $item['order_item_id'],
                            'warehouse_id' => $item['warehouse_id'],
                            'fl_warehouse_id' => $fl_warehouse_id,
                            'product_id' => $item['product_id'],
                            'is_futures' => $item['is_futures'],
                            'arrival_date' => $item['arrival_date'],
                            'real_arrival_date' => $item['real_arrival_date'],
                            'apply_quantity' => $item['apply_quantity'],
                            'pending_quantity' => $item['pending_quantity'],
                            'code' => $orderItem['code'] ?? '',
                            'name' => $orderItem['product_name'] ?? '',
                            'hashrate' => $orderItem['hashrate'] ?? '',
                            'expiration_date' => $orderItem['expiration_date'] ?? '',
                            'original_price' => $orderItem['original_price'] ?? '0.00',
                            'actual_price' => $orderItem['actual_price'] ?? '0.00',
                            'actual_selling_price' => $orderItem['price_selected_currency'],
                            'free_shipping' => $orderItem['free_shipping'] ?? 0,
                            'apply_rules' => $orderItem['apply_rules'] ?? 0,
                            'brand' => $orderItem['brand'] ?? 0,
                            'actual_quoted_currency' => $orderItem['transaction_currency_id'] ?? 0,
                            'actual_quoted_currency_name' => $currencyName,
                            'billing_weight' => $orderItem['billing_weight'] ?? '',
                            'pay_quantity' => $orderItem['quantity'] ?? 0,
                            'unique' => $orderItem['unique'] ?? '',
                            'creator' => $item['creator'],
                            'creator_name' => $creatorNames[$item['creator']] ?? ''
                        ];
                    }
                }
            }

            $result[] = $applyData;
        }

        return $this->success($result);
    }

    /**
     * @describe 创建部分发货申请
     * @param array $data 创建数据
     * @return array
     */
    public function create($data)
    {
        Db::startTrans();
        try {
            // 检查订单是否存在
            $order = $this->orderModel->where('id', $data['order_id'])->find();
            if (!$order) {
                return $this->error(400000, '订单不存在');
            }

            // 创建主表记录
            $mainData = [
                'order_id' => $data['order_id'],
                'remark' => $data['remark'] ?? '',
                'status' => 1,
                'creator' => $data['creator']
            ];

            $apply = $this->model->create($mainData);
            if (!$apply) {
                Db::rollback();
                return $this->error(500001, '创建申请失败');
            }

            // 处理申请项
            foreach ($data['items'] as $item) {
                // 检查订单项是否存在
                $orderItem = $this->orderItemModel->where([
                    ['id', '=', $item['order_item_id']],
                    ['order_id', '=', $data['order_id']]
                ])->find();

                if (!$orderItem) {
                    Db::rollback();
                    return $this->error(400000, '订单项不存在');
                }

                // 获取该订单项已申请的总数量
                $appliedQuantity = $this->itemModel->where([
                    ['order_item_id', '=', $item['order_item_id']],
                    ['is_del', '=', 0]
                ])->sum('apply_quantity');

                // 计算还可以申请的数量
                $remainingQuantity = $orderItem['quantity'] - ($appliedQuantity ?: 0);

                // 检查申请数量是否超过剩余可申请数量
                if ($item['apply_quantity'] > $remainingQuantity) {
                    Db::rollback();
                    return $this->error(400000, "订单项ID {$item['order_item_id']} 申请数量超过限制，最多还可申请 {$remainingQuantity} 个");
                }

                // 创建申请项记录
                $itemData = [
                    'order_part_delivery_apply_id' => $apply->id,
                    'order_item_id' => $item['order_item_id'],
                    'warehouse_id' => $orderItem['warehouse_id'],
                    'product_id' => $orderItem['product_id'],
                    'is_futures' => $orderItem['is_futures'],
                    'arrival_date' => $orderItem['arrival_date'],
                    'real_arrival_date' => $orderItem['real_arrival_date'],
                    'apply_quantity' => $item['apply_quantity'],
                    'pending_quantity' => $item['apply_quantity'],
                    'creator' => $data['creator']
                ];

                $result = $this->itemModel->create($itemData);
                if (!$result) {
                    Db::rollback();
                    return $this->error(500001, '创建申请项失败');
                }
            }

            Db::commit();
            $notificationService = new CompleteNotificationService();
            $notificationService->send('order_part_delivery_apply', $order->toArray());
            $this->logger->logOperation($data['order_id'], 'order', '订单-部分发货申请发起', '创建部分发货申请',1,'order_part_delivery_apply',$apply->id,'1,10');
            return $this->success();
        } catch (\Throwable $th) {
            Db::rollback();
            return $this->error(500001, '服务器内部错误：' . $th->getMessage());
        }
    }

    /**
     * 审核
     * @param array $data
     * @return array
     */
    public function approve($data)
    {
        // 获取申请记录
        $applyInfo = OrderPartDeliveryApplyModel::where([
            ['id', '=', $data['id']],
            ['is_del', '=', 0],
            ['status', '=', 1]
        ])->find();

        if (!$applyInfo) {
            return $this->error(400000, '申请记录不存在或已审核');
        }

        if ($data['status'] == 1) {


            // 获取订单信息
            $orderInfo = OrderModel::where([
                ['id', '=', $applyInfo['order_id']],
                ['is_del', '=', 0]
            ])->find();

            if (!$orderInfo) {
                return $this->error(400000, '订单不存在');
            }

            // 获取可部分发货比例
            $partDeliveryRatio = SystemConfigModel::where('key', 'PART_DELIVERY_PRODUCT_AMOUNT_RATIO')->value('value');
            $partDeliveryRatio = floatval($partDeliveryRatio ?: 0) / 100;

            // 计算可部分发货的金额总计
            $maxPartDeliveryAmount = $orderInfo['pay_amount'] * $partDeliveryRatio;

            // 获取已审核通过的申请商品金额汇总
            $approvedAmount = Db::name('order_part_delivery_apply_item')
                ->alias('item')
                ->join('order_part_delivery_apply apply', 'item.order_part_delivery_apply_id = apply.id')
                ->join('order_item oi', 'item.order_item_id = oi.id')
                ->where([
                    ['apply.order_id', '=', $applyInfo['order_id']],
                    ['apply.status', '=', 2],
                    ['apply.is_del', '=', 0],
                    ['item.is_del', '=', 0]
                ])
                ->sum(Db::raw('item.apply_quantity * oi.actual_price'));
            $approvedAmount += $data['part_delivery_amount'];

            // 检查总金额是否超出限制
            if ($approvedAmount > $maxPartDeliveryAmount) {
                return $this->error(500001, '超出可部分发货金额限制，审核不通过');
            }

            // 更新申请状态
            OrderPartDeliveryApplyModel::where('id', $data['id'])->update([
                'status' => 2,
                'updater' => $data['updater'] ?? 0,
                'update_time' => date('Y-m-d H:i:s')
            ]);


            $partnerArr = $orderInfo->partner ? array_filter(explode(',', $orderInfo->partner)) : [];
            $notificationService = new CompleteNotificationService();
            $notificationService->send('order_part_delivery_apply_passed', $orderInfo->toArray(), [$orderInfo->owner, $orderInfo->signatory, ...$partnerArr]);

            $this->logger->logOperation($applyInfo['order_id'], 'order', '订单-部分发货申请审核通过', '审核通过部分发货申请',1,'order_part_delivery_apply',$data['id']);
        } else {
            OrderPartDeliveryApplyModel::where('id', $data['id'])->update([
                'is_del' => time(),
                'updater' => $data['updater'] ?? 0,
                'update_time' => date('Y-m-d H:i:s')
            ]);
            $this->logger->logOperation($applyInfo['order_id'], 'order', '订单-部分发货申请审核驳回', '驳回部分发货申请',1,'order_part_delivery_apply',$data['id']);

        }
        $approverWhere = [
            'entity_id' => $applyInfo['order_id'],
            'child_entity_id' => $data['id'],
            'child_business_module' => 'order_part_delivery_apply',
            'business_module' => 'order',
            'operate' => '订单-申请部分发货',

        ];
        $this->logger->updateApprover($approverWhere,$data['updater']);
        return $this->success();
    }


    /**
     * 撤销
     * @param array $data
     * @return array
     */
    public function cancel($data)
    {
        // 获取申请记录
        $applyInfo = OrderPartDeliveryApplyModel::where([
            ['id', '=', $data['id']],
            ['is_del', '=', 0],
            ['creator', '=', $data['creator']],
            ['status', '=', 1]
        ])->find();

        if (!$applyInfo) {
            return $this->error(400000, '申请记录不存在或已审核');
        }


        OrderPartDeliveryApplyModel::where('id', $data['id'])->update([
            'is_del' => time(),
            'updater' => $data['creator'] ?? 0,
            'update_time' => date('Y-m-d H:i:s')
        ]);
        $this->logger->logOperation($applyInfo['order_id'], 'order', '订单-部分发货申请撤销', '撤销部分发货申请', 1, 'order_part_delivery_apply', $data['id']);

        return $this->success();
    }
}
